<!--
 * 图片
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-image" :class="classes" :style="styles" :hover-class="hoverClass" @tap="handleClick">
        <!-- 图片 -->
        <image
            class="pure-image-image"
            :src="src"
            :mode="mode"
            :lazy-load="lazyLoad"
            :fade-show="fadeShow"
            :webp="webp"
            :show-menu-by-longpress="showMenuByLongpress"
            :draggable="draggable"
            v-if="showImage"
        />

        <!-- 占位图 -->
        <image
            class="pure-image-placeholder"
            :src="placeholder"
            :mode="mode"
            :lazy-load="lazyLoad"
            :fade-show="fadeShow"
            :webp="webp"
            :show-menu-by-longpress="showMenuByLongpress"
            :draggable="draggable"
            v-else-if="showPlaceholder"
        />

        <!-- 加载中 -->
        <view class="pure-image-status pure-image-loading" v-else-if="showLoading">
            <!-- 兼容京东多slot写法 -->
            <slot name="loading" v-if="$slots.loading"></slot>

            <view class="pure-image-status-icon pure-image-loading-icon" :class="{ 'pure-image-loading-icon-spin': loadingSpin }" v-if="!$slots.loading">
                <pure-icon :name="loadingIcon" :mode="loadingMode"></pure-icon>
            </view>
            <text class="pure-image-status-text pure-image-loading-text" v-if="loadingText && !$slots.loading">{{ loadingText }}</text>
        </view>

        <!-- 加载失败 -->
        <view class="pure-image-status pure-image-fail" v-else-if="showFail">
            <!-- 兼容京东多slot写法 -->
            <slot name="fail" v-if="$slots.fail"></slot>

            <view class="pure-image-status-icon pure-image-fail-icon" v-if="!$slots.fail">
                <pure-icon :name="failIcon" :mode="failMode"></pure-icon>
            </view>
            <text class="pure-image-status-text pure-image-fail-text" v-if="failText && !$slots.fail">{{ failText }}</text>
        </view>

        <!-- 预加载图片 -->
        <view class="pure-image-preload">
            <image :src="src" :mode="mode" @load="handleLoad" @error="handleError" />
            <image :src="placeholder" :mode="mode" @load="handlePlaceholderLoad" @error="handlePlaceholderError" />
        </view>
    </view>
</template>

<script>
    import props from "./props.js";
    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props,
        emits: ["onClick", "error", "load"],
        data() {
            return {
                // 加载状态
                // loading: 加载中
                // success: 加载成功
                // fail: 加载失败
                loadStatus: "loading",

                // 占位图状态
                placeholderStatus: "loading",
            };
        },
        computed: {
            // classes
            classes() {
                const classes = [];

                // 圆形图片
                if (this.circle) classes.push("pure-image-circle");

                return classes;
            },

            // styles
            styles() {
                const styles = [];

                // 宽高
                if (this.width) styles.push(`--pure-image-width-prop: ${this.width};`);
                if (this.height) styles.push(`--pure-image-height-prop: ${this.height};`);

                // widthFix
                if (this.mode === "widthFix") styles.push(`--pure-image-height: auto;`);

                // heightFix
                if (this.mode === "heightFix") styles.push(`--pure-image-width: auto;`);

                return styles;
            },

            // 是否显示图片
            showImage() {
                return this.src && this.loadStatus === "success";
            },

            // 是否显示占位图
            showPlaceholder() {
                return this.placeholder && this.placeholderStatus === "success";
            },

            // 是否显示加载中
            showLoading() {
                // 无占位图
                if (!this.placeholder) {
                    return this.loadStatus === "loading";
                }

                // 有占位图
                else {
                    return this.loadStatus === "loading" && this.placeholderStatus === "loading";
                }
            },

            // 是否显示加载失败
            showFail() {
                // 无占位图
                if (!this.placeholder) {
                    return this.loadStatus === "fail";
                }

                // 有占位图
                else {
                    return this.loadStatus === "fail" && this.placeholderStatus === "success";
                }
            },
        },
        watch: {
            // 监听图片路径变化
            src: {
                handler() {
                    // 初始化加载状态
                    this.loadStatus = "loading";
                },
                immediate: true,
            },

            // 监听占位图路径变化
            placeholder: {
                handler() {
                    // 初始化加载状态
                    this.placeholderStatus = "loading";
                },
                immediate: true,
            },
        },
        methods: {
            // 点击事件
            handleClick() {
                // 禁用了
                if (this.disabled) return;

                // 提交事件
                this.$emit("onClick", this.src);

                // 开启了点击预览
                if (this.preview) {
                    uni.previewImage({
                        urls: [this.src],
                        current: 0,
                    });
                }
            },

            // 加载完成
            handleLoad(e) {
                // 提交事件
                this.$emit("load", e);

                // 更新加载状态
                this.loadStatus = "success";
            },

            // 加载失败
            handleError(e) {
                // 提交事件
                this.$emit("error", e);

                // 更新加载状态
                this.loadStatus = "fail";
            },

            // 占位图加载完成
            handlePlaceholderLoad(e) {
                // 更新加载状态
                this.placeholderStatus = "success";
            },

            // 占位图加载失败
            handlePlaceholderError(e) {
                // 更新加载状态
                this.placeholderStatus = "fail";
            },
        },
    };
</script>

<style scoped>
    @import "./style.css";
</style>
